package net.jgrm.multilevelcache.sync;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 缓存同步消息
 * 用于在分布式环境下同步多个实例的本地缓存
 *
 * @author jgrm
 */
public class CacheSyncMessage implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 操作类型
     */
    public enum OperationType {
        /**
         * 删除缓存项
         */
        EVICT,
        /**
         * 清空整个缓存
         */
        CLEAR,
        /**
         * 更新缓存项
         */
        PUT
    }

    /**
     * 缓存名称
     */
    private final String cacheName;

    /**
     * 缓存键
     */
    private final Object key;

    /**
     * 缓存值（仅PUT操作时使用）
     */
    private final Object value;

    /**
     * 操作类型
     */
    private final OperationType operationType;

    /**
     * 发送实例ID（避免自己接收自己发送的消息）
     */
    private final String sourceInstanceId;

    /**
     * 消息发送时间
     */
    private final LocalDateTime timestamp;

    @JsonCreator
    public CacheSyncMessage(
            @JsonProperty("cacheName") String cacheName,
            @JsonProperty("key") Object key,
            @JsonProperty("value") Object value,
            @JsonProperty("operationType") OperationType operationType,
            @JsonProperty("sourceInstanceId") String sourceInstanceId) {
        this.cacheName = cacheName;
        this.key = key;
        this.value = value;
        this.operationType = operationType;
        this.sourceInstanceId = sourceInstanceId;
        this.timestamp = LocalDateTime.now();
    }

    /**
     * 创建删除缓存消息
     */
    public static CacheSyncMessage evict(String cacheName, Object key, String sourceInstanceId) {
        return new CacheSyncMessage(cacheName, key, null, OperationType.EVICT, sourceInstanceId);
    }

    /**
     * 创建清空缓存消息
     */
    public static CacheSyncMessage clear(String cacheName, String sourceInstanceId) {
        return new CacheSyncMessage(cacheName, null, null, OperationType.CLEAR, sourceInstanceId);
    }

    /**
     * 创建更新缓存消息
     */
    public static CacheSyncMessage put(String cacheName, Object key, Object value, String sourceInstanceId) {
        return new CacheSyncMessage(cacheName, key, value, OperationType.PUT, sourceInstanceId);
    }

    // Getters
    public String getCacheName() {
        return cacheName;
    }

    public Object getKey() {
        return key;
    }

    public Object getValue() {
        return value;
    }

    public OperationType getOperationType() {
        return operationType;
    }

    public String getSourceInstanceId() {
        return sourceInstanceId;
    }

    public LocalDateTime getTimestamp() {
        return timestamp;
    }

    @Override
    public String toString() {
        return "CacheSyncMessage{" +
                "cacheName='" + cacheName + '\'' +
                ", key=" + key +
                ", operationType=" + operationType +
                ", sourceInstanceId='" + sourceInstanceId + '\'' +
                ", timestamp=" + timestamp +
                '}';
    }
}